# code_sample/package/utility.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*

import os
import json
import numpy
import subprocess

def ensure_exists(target):
    if not os.path.exists(target):
        raise FileNotFoundError(f"{target} not exists!")

def find_targets(topdir, pattern, suffix=""):
    """find targets under topdir with the specified filename pattern"""
    topdir = os.path.abspath(topdir)
    ensure_exists(topdir)

    command = f"find {topdir} -name \"{pattern}\" {suffix}" # 找 topdir 下 名字含有 pattern 的文件
    ret, output = subprocess.getstatusoutput(command)
    if ret != 0:
        raise RuntimeError(f"failed to run: {command}, ret={ret}, output={output}")

    targets = output.split("\n")
    return targets

def find_sub_targets(topdir, pattern, suffix=""):
    """find targets under topdir with the specified filename pattern"""
    topdir = os.path.abspath(topdir)
    ensure_exists(topdir)

    command = f"find {topdir} -mindepth 1 -maxdepth 1 -name \"{pattern}\" {suffix}" # 找 topdir 下 名字含有 pattern 的文件
    ret, output = subprocess.getstatusoutput(command)
    if ret != 0:
        raise RuntimeError(f"failed to run: {command}, ret={ret}, output={output}")

    targets = output.split("\n")
    return targets

def scan_runcases(topdir):
    """scan runcase under topdir."""
    topdir = os.path.abspath(topdir)
    ensure_exists(topdir)

    print(f">> scan runcase under {topdir}") 
    runcases = find_targets(topdir, "reapet*", suffix="-xtype d") 
    runcase_num = len(runcases)
    print(f">> {runcase_num} runcases found!")

    return runcases

def scan_srunoutlog(topdir):
    """scan sub.result under topdir."""
    topdir = os.path.abspath(topdir)
    ensure_exists(topdir)

    print(f">> scan sub.result under {topdir}") 
    runcases = find_targets(topdir, "sub.result", suffix="-xtype f") 
    runcase_num = len(runcases)
    print(f">> {runcase_num} sub.result found!")

    return runcases

def load_runcase_npt_config(reapet_dir):
    """load npt config of the runcase"""
    ensure_exists(reapet_dir)
    case_rundir = os.path.dirname(reapet_dir)
    case_rundir = os.path.join(case_rundir,"..")
    case_rundir = os.path.abspath(case_rundir)
    # case_config = os.path.join(case_rundir, "*info.json")
    case_config = find_targets(case_rundir, "*info.json", suffix="-xtype f")[0]
    ensure_exists(case_config)
    with open(case_config, "r", encoding="utf-8") as fp:
        config = json.load(fp)
    
    node_num = config["argument"]["nodes"]
    if isinstance(node_num, list):
        node_num = len(node_num)
    proc_num = config["argument"]["numprocess"]
    iter_num = config["argument"]["rt"]

    return (node_num, proc_num, iter_num)

def load_pidtimer_data(pidtimer):
    """load pid's timer data from pidxxx.json"""
    with open(pidtimer, "r", encoding="utf-8") as fp:
        data = json.load(fp)

    return data

def get_minmaxmean(datalist):
    list2array = numpy.array(datalist)
    min_val = list2array.min()
    max_val = list2array.max()
    ave_val = list2array.mean()

    return (min_val, max_val, ave_val)